import type { Router, RouteRecordNormalized, RouteRecordRaw } from 'vue-router';
import NProgress from 'nprogress';
import { NOT_FOUND_ROUTE } from '@/router/routes/base';
import { useAppStore } from '@/store';
import { isLogin } from '@/utils/auth';
import { WHITE_LIST, NOT_FOUND, DEFAULT_ROUTE } from '../constants';

const MODULES = import.meta.glob('../../views/**/**/**.vue');

const parseURL = (url: string | null | undefined
): { basePath: string; paramsObject: { [key: string]: string } } => {
  // 如果输入为 null 或 undefined，返回空字符串和空对象
  if (url == null) {
    return { basePath: '', paramsObject: {} };
  }
  // 找到问号 (?) 的位置，它之前是基础路径，之后是查询参数
  const questionMarkIndex = url.indexOf('?');
  let basePath = url;
  const paramsObject: { [key: string]: string } = {};
  // 如果找到了问号，说明有查询参数
  if (questionMarkIndex !== -1) {
    // 获取 basePath
    basePath = url.substring(0, questionMarkIndex);
    // 从 URL 中获取查询字符串部分
    const queryString = url.substring(questionMarkIndex + 1);
    // 使用 URLSearchParams 遍历参数
    const searchParams = new URLSearchParams(queryString);
    searchParams.forEach((value, key) => {
      // 封装进 paramsObject 对象
      paramsObject[key] = value;
    });
  }
  // 返回 basePath 和 paramsObject
  return { basePath, paramsObject };
};

const filterAsyncRoutes = (routes: RouteRecordRaw[]) => {
  const asyncRoutes: RouteRecordRaw[] = [];
  routes.forEach((route) => {
    const tmpRoute = { ...route }; // ES6扩展运算符复制新对象
    tmpRoute.component = tmpRoute.component?.toString() === 'DEFAULT_LAYOUT'
      ? () => import('@/layout/default-layout.vue')
      : MODULES[`../../views/${tmpRoute.component}.vue`];
    if (tmpRoute.children && tmpRoute.children.length > 0) {
      tmpRoute.children = filterAsyncRoutes(tmpRoute.children);
    }
    asyncRoutes.push(tmpRoute);
  });
  return asyncRoutes;
};

export default function setupPermissionGuard(router: Router) {
  router.beforeEach(async (to, from, next) => {
    const appStore = useAppStore();
    if (!appStore.appAsyncMenus.length && !WHITE_LIST.find((el) => el.name === to.name)) {
      await appStore.fetchServerMenuConfig(router);
      const asyncRoutes = filterAsyncRoutes(appStore.appAsyncMenus);
      asyncRoutes.forEach((route) => {
        router.addRoute(route);
      });
      router.addRoute(NOT_FOUND_ROUTE);
    }
    let exist = false;
    const serverMenuConfig = [...appStore.appAsyncMenus, ...WHITE_LIST, DEFAULT_ROUTE];
    while (serverMenuConfig.length && !exist) {
      const element = serverMenuConfig.shift();
      if (element?.name === to.name) {
        exist = true;
      }
      if (element?.children) {
        serverMenuConfig.push(...(element.children as unknown as RouteRecordNormalized[]));
      }
    }
    if (exist || !to.name) {
      if (to.path === '/login') {
        if (isLogin()) {
          next(DEFAULT_ROUTE);
        } else {
          next();
        }
      } else {
        // 修复跳转时不带参数的问题
        const redirectPath = from.query.redirect || to.path;
        const redirect = decodeURIComponent(redirectPath as string);
        const { basePath, paramsObject: query } = parseURL(redirect);
        const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect, query };
        if (to.name) {
          next();
        } else {
          next(nextData);
        }
      }
    } else {
      next(NOT_FOUND);
    }
    NProgress.done();
  });
}
